package org.abc.fund.entity.combination; // 请确保包名正确

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 组合产品实体类
 * 职责：精确映射数据库中的 'combination_products' 表结构。
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Table(name = "combination_products")
public class CombinationProduct {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(name = "risk_level")
    private String riskLevel;

    private String strategy;
    private String features;

    public enum Status {
        DRAFT,
        PENDING_APPROVAL,
        REJECTED,
        APPROVED,
        INACTIVE
    }

    @Enumerated(EnumType.STRING)
    private Status status = Status.DRAFT;

    @Column(name = "creator_id")
    private Long creatorId;

    @Column(name = "approver_id")
    private Long approverId;

    /**
     * 创建时间戳。
     * @CreationTimestamp 注解使得在实体第一次被保存时，Hibernate会自动填充当前时间。
     * updatable = false 确保这个字段在后续更新时不会被改变。
     */
    @CreationTimestamp
    @Column(name = "create_time", updatable = false)
    private Date createTime;

    /**
     * 更新时间戳。
     * @UpdateTimestamp 注解使得在实体每次更新时，Hibernate会自动填充当前时间。
     */
    @UpdateTimestamp
    @Column(name = "update_time")
    private Date updateTime;

    @Column(name = "approval_time")
    private Date approvalTime;

    private String rejectionReason;

    /**
     * 定义与 CombinationHolding 的一对多关系。
     * 这是关系的核心配置。
     * * - mappedBy = "combinationProduct":
     * 指明这个关系是由 CombinationHolding 实体中的 'combinationProduct' 字段来维护的。
     * 这确立了 CombinationProduct 是关系的“主控方”(inverse side)。
     * * - cascade = CascadeType.ALL:
     * 设置级联操作。这意味着对 CombinationProduct 的所有操作（保存、更新、删除等）
     * 都会自动应用到其关联的 holdings 列表中的所有 CombinationHolding 实体。
     * 例如，当你保存一个 Product 时，它列表里的新 Holding 也会被自动保存。
     *
     * - orphanRemoval = true:
     * “孤儿移除”是一个非常重要的优化。当一个 CombinationHolding 从这个 holdings 列表中被移除时，
     * 它就成了一个“孤儿”（不再被任何 Product 关联）。此设置会确保这个“孤儿”实体被自动从数据库中删除。
     * 这对于更新操作（例如，替换整个持仓列表）至关重要。
     * * - fetch = FetchType.LAZY:
     * 设置“懒加载”。这意味着在查询 CombinationProduct 时，Hibernate 不会立即去数据库加载其关联的
     * holdings 列表。只有当你第一次尝试访问 product.getHoldings() 时，才会真正执行查询。
     * 这能极大地提升性能，避免不必要的数据库查询，特别是在查询产品列表时。
     */
    @OneToMany(
            mappedBy = "combinationProduct",
            cascade = CascadeType.ALL,
            orphanRemoval = true,
            fetch = FetchType.LAZY
    )

    private List<CombinationHolding> holdings = new ArrayList<>();
}